﻿using SBlogCore.Entitys.SystemManager;
using SBlogCore.WebAdminApplication.SysManager.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SBlogCore.Enums;
using SBlogCore.TaskJob;
using Quartz;
using Microsoft.Extensions.Logging;
using SBlogCore.Application.Demo.Controllers;
using SBlogCore.WebAdminApplication.SysUserManager.IServices;

namespace SBlogCore.WebAdminApplication.SysManager.Services
{
    public class SysOpenJobService
    {
        private readonly ILogger<SysOpenJobService> _logger;
        private readonly IRepository<SysOpenJob> _openJob;
        private readonly ISchedulerFactory _schedulerFactory;
        private readonly ISysUserInfoService _userInfoService;

        public SysOpenJobService(
            ILogger<SysOpenJobService> logger,
            IRepository<SysOpenJob> openJob,
            ISchedulerFactory schedulerFactory,
            ISysUserInfoService userInfoService)
        {
            _logger = logger;
            _openJob = openJob;
            _schedulerFactory = schedulerFactory;
            _userInfoService = userInfoService;
        }
        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <returns></returns>
        public  async Task<List<SysOpenJob>> GetList()
        {
            var list = await _openJob.Where(w => true).ToListAsync();
            return list;
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="inPut"></param>
        /// <returns></returns>
        public async Task Add(SysOpenJob inPut)
        {
            if (string.IsNullOrEmpty(inPut.JobId))
            {
                inPut.JobId = Guid.NewGuid().ToString();
            }
            else
            {
                if (await _openJob.AnyAsync(w => w.JobId == inPut.JobId))
                    throw SBlogCoreException.Say($"任务ID{inPut.JobId}已存在！");
            }
            await _openJob.InsertNowAsync(inPut);
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="inPut"></param>
        /// <returns></returns>
        public async Task Update(SysOpenJobUpdateInPut inPut)
        {
            var info = await _openJob.FirstOrDefaultAsync(w => w.Id == inPut.Id);
            if (info == null)
                throw SBlogCoreException.Say($"数据不存在！");
            if (string.IsNullOrEmpty(inPut.JobId))
            {
                inPut.JobId = Guid.NewGuid().ToString();
            }
            else
            {
                if (await _openJob.AnyAsync(w => w.JobId == inPut.JobId&&w.Id!=inPut.Id))
                    throw SBlogCoreException.Say($"任务ID{inPut.JobId}已存在！");
            }
            info.JobId=inPut.JobId;
            info.JobName = inPut.JobName!;
            info.JobType = inPut.JobType;
            info.JobCall = inPut.JobCall!;
            info.JobCallParams = inPut.JobCallParams??string.Empty;
            info.Cron = inPut.Cron!;
            await _openJob.UpdateNowAsync(info);
        }

        /// <summary>
        /// 批量启动
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task Start(List<long> ids, CancellationToken cancellationToken = default) 
        {
            var list = await _openJob.Where(w => ids.Contains(w.Id) && w.Status != (int)JobStatusEnum.Running).ToListAsync(cancellationToken);
            var userInfo = await _userInfoService.GetLoginUserInfo();
            foreach (var info in list)
            {
                var scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
                var job = OpenJobBuilder.Build(scheduler);
                await job.BindJob(info).RunAsync(cancellationToken);
                Serilog.Log.ForContext("OpenJob", info.JobId).Information($"用户：{userInfo.UserName}在{DateTime.Now:yyyy-MM-dd HH:mm:ss}启动任务:{info.JobName}");
            }
        }
        /// <summary>
        /// 批量暂停
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task Stop(List<long> ids, CancellationToken cancellationToken = default)
        {
            var list = await _openJob.Where(w => ids.Contains(w.Id) && w.Status == (int)JobStatusEnum.Running).ToListAsync(cancellationToken);
            var userInfo = await _userInfoService.GetLoginUserInfo();
            foreach (var info in list)
            {
                var scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
                var job = OpenJobBuilder.Build(scheduler);
                await job.BindJob(info).StopAsync(cancellationToken);
                Serilog.Log.ForContext("OpenJob", info.JobId).Information($"用户：{userInfo.UserName}在{DateTime.Now:yyyy-MM-dd HH:mm:ss}停止任务:{info.JobName}");
            }
        }
        /// <summary>
        /// 创建执行日志
        /// </summary>
        /// <param name="jobId"></param>
        /// <returns></returns>
        public async Task CreateExLog(string jobId)
        {
            var info = await _openJob.FirstOrDefaultAsync(w => w.JobId == jobId);
            if (info == null)
            {
                Serilog.Log.ForContext("OpenJob", jobId).Information($"任务Id:{jobId}不存在");
            }
            else
            {
                info.RunCount++;
                info.LastRunTime = DateTime.Now;
                Serilog.Log.ForContext("OpenJob", jobId).Information($"任务:{info.JobName}{DateTime.Now:yyyy-MM-dd HH:mm:ss}自动执行");
                await _openJob.UpdateNowAsync(info);
            }
            
        }
    }
}
